/**
 * @file Modbus_TCP.h
 * @author Linquan 
 * @brief 
 * @version 0.1
 * @date 2025-06-09
 * 
 * @copyright Copyright (c) 2025
 * 
 * @ history
 * 2025-6-9
 *      第一版，完成ModbusTCP的一个通用流程，创建一个网口对象，从网口接收到数据，然后扔到 MBpoll里解析。
 *      目前只完成了 handle he send函数的数据流转。
 *  下一步需要增加功能码支持，优先 02 03 06。依据freemodbus框架的功能码解析，将handle放到功能码解析函数里调用，
 *  handle传参增加功能码。
 * 然后需要将宏的名称进行修改
 */

#include "stdint.h"
// MUTI_MB
/* 功能函数的返回值协议约定的错误码 */
typedef enum
{
    MUTI_MB_EX_NONE = 0x00,
    MUTI_MB_EX_ILLEGAL_FUNCTION = 0x01,
    MUTI_MB_EX_ILLEGAL_DATA_ADDRESS = 0x02,
    MUTI_MB_EX_ILLEGAL_DATA_VALUE = 0x03,
    MUTI_MB_EX_SLAVE_DEVICE_FAILURE = 0x04,
    MUTI_MB_EX_ACKNOWLEDGE = 0x05,
    MUTI_MB_EX_SLAVE_BUSY = 0x06,
    MUTI_MB_EX_MEMORY_PARITY_ERROR = 0x08,
    MUTI_MB_EX_GATEWAY_PATH_FAILED = 0x0A,
    MUTI_MB_EX_GATEWAY_TGT_FAILED = 0x0B
} eMUTI_MB_Exception;


 /* 协议回调对应的错误码 */
typedef enum
{
    MUTI_MB_ENOERR,                  /*!< no error. */
    MUTI_MB_ENOREG,                  /*!< illegal register address. 锟角凤拷锟斤拷址*/
    MUTI_MB_EINVAL,                  /*!< illegal argument. */
    MUTI_MB_EPORTERR,                /*!< porting layer error. */
    MUTI_MB_ENORES,                  /*!< insufficient resources. */
    MUTI_MB_EIO,                     /*!< I/O error. */
    MUTI_MB_EILLSTATE,               /*!< protocol stack in illegal state. */
    MUTI_MB_ETIMEDOUT                /*!< timeout error occurred. */
} eMUTI_MB_ErrorCode;

/* 报文PDU的偏移量 */
#define MUTI_MB_PDU_SIZE_MAX     253 /*!< Maximum size of a PDU. */
#define MUTI_MB_PDU_SIZE_MIN     1   /*!< Function Code */
#define MUTI_MB_PDU_FUNC_OFF     0   /*!< Offset of function code in PDU. */
#define MUTI_MB_PDU_DATA_OFF     1   /*!< Offset for response data in PDU. */



/* ----------------功能码------ Defines ------------------------------------------*/
#define MUTI_MB_ADDRESS_BROADCAST    ( 0 )   /*! Modbus broadcast address. */
#define MUTI_MB_ADDRESS_MIN          ( 1 )   /*! Smallest possible slave address. */
#define MUTI_MB_ADDRESS_MAX          ( 247 ) /*! Biggest possible slave address. */
#define MUTI_MB_FUNC_NONE                          (  0 )
#define MUTI_MB_FUNC_READ_COILS                    (  1 )
#define MUTI_MB_FUNC_READ_DISCRETE_INPUTS          (  2 )
#define MUTI_MB_FUNC_WRITE_SINGLE_COIL             (  5 )
#define MUTI_MB_FUNC_WRITE_MULTIPLE_COILS          ( 15 )
#define MUTI_MB_FUNC_READ_HOLDING_REGISTER         (  3 )
#define MUTI_MB_FUNC_READ_INPUT_REGISTER           (  4 )
#define MUTI_MB_FUNC_WRITE_REGISTER                (  6 )
#define MUTI_MB_FUNC_WRITE_MULTIPLE_REGISTERS      ( 16 )
#define MUTI_MB_FUNC_READWRITE_MULTIPLE_REGISTERS  ( 23 )
#define MUTI_MB_FUNC_DIAG_READ_EXCEPTION           (  7 )
#define MUTI_MB_FUNC_DIAG_DIAGNOSTIC               (  8 )
#define MUTI_MB_FUNC_DIAG_GET_COM_EVENT_CNT        ( 11 )
#define MUTI_MB_FUNC_DIAG_GET_COM_EVENT_LOG        ( 12 )
#define MUTI_MB_FUNC_OTHER_REPORT_SLAVEID          ( 17 )
#define MUTI_MB_FUNC_ERROR                         ( 128 )

/*对功能寄存器的读写*/
typedef enum
{
    MB_REG_READ,                /*!< Read register values and pass to protocol stack. */
    MB_REG_WRITE,                /*!< Update register values. */
} eMUTI_MB_RegisterMode;



typedef uint8_t BOOL;

typedef uint8_t UCHAR;
typedef int8_t CHAR;

typedef uint16_t USHORT;
typedef int16_t SHORT;

typedef uint32_t ULONG;
typedef int32_t LONG;

#ifndef TRUE
#define TRUE            1
#endif

#ifndef FALSE
#define FALSE           0
#endif

/***************modbus 对象************************************/

typedef eMUTI_MB_ErrorCode (*MUTI_MB_handle_ptr)(uint8_t function_code, uint8_t * pucFrame,\
                                    uint16_t Address, uint16_t some_num, eMUTI_MB_RegisterMode wr_Mode);
                                    
typedef void (*MUTI_MB_send_ptr)(UCHAR* fram_ptr, uint16_t len);



// MB协议类型，同时也是设备地址
typedef enum
{
    MUTI_MB_TCP = 0,
	MUTI_MB_RTU_1,
	MUTI_MB_RTU_2,
	MUTI_MB_RTU_3,
	MUTI_MB_RTU_4,
	MUTI_MB_RTU_5,
	MUTI_MB_RTU_6,
}MUTI_MB_ID_t;




typedef enum
{
    IDLE,
    RECVED,
    EXCUTE,
    SEND
}MUTI_MB_state_t;


typedef enum
{
    NO_ACTIVE = 0,
    ACTIVE = ~NO_ACTIVE,
}MUTI_MB_active_t;


typedef struct 
{
	MUTI_MB_ID_t MB_id;
    MUTI_MB_state_t state;
    MUTI_MB_active_t active;
    uint8_t function_code;
    uint8_t buf[256];
    uint16_t len;
    MUTI_MB_handle_ptr protocol_cb;
    MUTI_MB_send_ptr   send_cb;

}MUTI_MB_object_t;






/**功能码列表结构体 */

typedef         eMUTI_MB_Exception( *MUTI_MB_FunctionHandler_ptr ) (MUTI_MB_object_t *obj, uint8_t * pucFrame, uint16_t * pusLength );

typedef struct
{
    uint8_t  ucFunctionCode;
    MUTI_MB_FunctionHandler_ptr pxHandler;
} xMUTI_MB_FunctionHandler;







void MUTI_MB_object_init(MUTI_MB_object_t *object,
						 MUTI_MB_ID_t	 MB_ID,
						 MUTI_MB_handle_ptr     handle_cb,
						 MUTI_MB_send_ptr       send_cb);

uint8_t MUTI_MB_data_append(MUTI_MB_object_t *object, const uint8_t* data, uint16_t len);

void MUTI_MB_poll(MUTI_MB_object_t *object);




